#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "TGI/TGI.h"
#include "TIN/TIN.h"
#include "lib/Lsimple.h"
#include "lib/Colas.h"
#include "lib/Pilas.h"
#ifndef OK
	#define OK 0
#endif
#ifndef ERROR_N_FOUND
	#define ERROR_N_FOUND 1
#endif


TIN tin;
TCola incidencias2;
TListaSimple incidencias3;
TGI tgi;
user_t usuario;
project_t proyecto;
inci_comment_t comentarios;
FILE *file;
char respuesta;


char *program_name;				 /* Nombre de ejecucion del programa (para errores e informacion) */
char *proyect_file=NULL;	/* Nombre archivo de proyectos */
char *user_file=NULL;			/* Nombre archivo de usuarios*/
char *inci_file=NULL;			/* Nombre archivo de incidencias*/
tipo_inci_t inci_tipo;
prior_inci_t inci_prior;
stat_inci_t inci_stat;
char *estado;
resol_inci_t inci_resol;
char *username;
char *proyname;
char *fecha = NULL;
char *inci_summ = NULL;
char *inci_desc = NULL;

int sin_configuracion = 1;	/* Configuracion de documentacion por defecto (default = true) */
int accion = 0;				/* Accion que se esta realizando, necesaria para saber que tipo de parametros son aceptados*/
int exeStatus = 0;
int usr;
int id_u_create, id_u_asig, inci_n_proy,inci_ID;
/*
* verifica la existencia del archivo indicado
*/
int file_exists(const char * filename){
	if (file = fopen(filename, "r")){ /*Prueba de apertura para lectura*/
		fclose(file);
		return OK;
	}
	return ERROR_N_FOUND;
}

/*
 * si se ingresa parametros incorectos se imprime la informacion de uso	 *
 */
void uso(void){
	fprintf(stderr,"Manipulacion de incidencias\n");
	fprintf(stderr,"El uso es %s [configuracion -I -P -U] [file] | [Accion] [Dato -t -p] [valor]\n",program_name);
	fprintf(stderr,"Configuracion\n");
	fprintf(stderr,"  -I <nombre-arch>          Archivo de Incidencias\n");/*0*/
	fprintf(stderr,"  -P <nombre-arch>          Archivo de proyectos\n");/*0*/
	fprintf(stderr,"  -U <nombre-arch>          Archivo de usuarios\n");/*0*/
	fprintf(stderr,"Acciones\n");/*0*/
	fprintf(stderr,"  -A                        Agregar incidencia\n");/*1*/
	fprintf(stderr,"     -tpuafnsd <datos>\n");
	fprintf(stderr,"  -E                        Cambiar estado\n");/*2*/
	fprintf(stderr,"     -ifue\n");
	fprintf(stderr,"  -R                        Resolver incidencia\n");/*3*/
	fprintf(stderr,"     -ifur\n");
	fprintf(stderr,"  -O                        Obtener datos incidencia\n");/*4*/
	fprintf(stderr,"     -i\n");
	fprintf(stderr,"  -C                        Ontener comentarios incidencia\n");/*5*/
	fprintf(stderr,"     -i\n");
	fprintf(stderr,"  -S                        Ontener incidencias usuario\n");/*6*/
	fprintf(stderr,"     -u\n");
	fprintf(stderr,"  -Y                        Ontener incidencias proyecto\n");/*7*/
	fprintf(stderr,"     -n\n");
	fprintf(stderr,"  -T                        Agregar un proyecto\n");/*8*/
	fprintf(stderr,"     -j\n");
	fprintf(stderr,"  -G                        Agregar un usuario\n");/*9*/
	fprintf(stderr,"     -k\n");
/*Datos de la incidencia*/
	fprintf(stderr,"  Datos de la incidencia\n");
	fprintf(stderr,"  -i <id>                   ID de la incidencia\n");
	fprintf(stderr,"  -t <Tipo>                 Tipo de la incidencia\n");
	fprintf(stderr,"      0                       Error\n");
	fprintf(stderr,"      1                       Mejora\n");
	fprintf(stderr,"      2                       Nueva Funcionalidad\n");
	fprintf(stderr,"      3                       Tarea\n");
	fprintf(stderr,"  -r <Resolucion>             Resolucion de la incidencia\n");
	fprintf(stderr,"      0                       Solucionado\n");
	fprintf(stderr,"      1                       No solucionado\n");
	fprintf(stderr,"      2                       incompleto\n");
	fprintf(stderr,"  -p <Prioridad>            Prioridad de la incidencia\n");
    fprintf(stderr,"      0                       Bloqueante\n");
	fprintf(stderr,"      1                       Critica\n");
	fprintf(stderr,"      2                       Mayor\n");
	fprintf(stderr,"      3                       Menor\n");
	fprintf(stderr,"      4                       Trivial\n");
	fprintf(stderr,"  -e <Estado>               Estado de la incidencia\n");
    fprintf(stderr,"      0                       Abierta\n");
	fprintf(stderr,"      1                       En progreso\n");
	fprintf(stderr,"      2                       Resuelta\n");
	fprintf(stderr,"      3                       Reabierta\n");
	fprintf(stderr,"      4                       Cerrada\n");
	fprintf(stderr,"  -u <User-id>              ID del usuario\n");
	fprintf(stderr,"  -k <User-name>            Nombre del usuario\n");
	fprintf(stderr,"  -a <User-id>              ID del usuario asignado\n");
	fprintf(stderr,"  -f <Fecha creacion/modif> Fecha de creacion o de\n");
  fprintf(stderr,"                               modificacion de la \n");
	fprintf(stderr,"                               incidencia en el formato\n");
	fprintf(stderr,"                               dd/mm/aaaa\n");
	fprintf(stderr,"  -n <Proyect-id>           Numero de identificacion del\n");
  fprintf(stderr,"                               Proyecto\n");
	fprintf(stderr,"  -j <Proyect-name>         Nombre del Proyecto\n");
  fprintf(stderr,"  -s <\"Resumen\">          Resumende la incidencia\n");
  fprintf(stderr,"  -d <\"Descripcion\">      Descripcion de la incidencia\n");

  exit (8);
}/*USO*/

int configuracion(char* program_name,char* proyect_file,char* user_file,char* inci_file){
    FILE *file_tmp;
    char* temporal=(char*)malloc(sizeof(char)*(strlen(program_name)));
	temporal = strdup(program_name);
	temporal=realloc(temporal, sizeof(char)*(strlen(program_name)+5));
    strcat(temporal,".ini");
    printf("temporal %s\n",temporal);
	if (file_tmp = fopen(temporal, "w")){
		fprintf(file_tmp,"%s\n",proyect_file);
		fprintf(file_tmp,"%s\n",user_file);
		fprintf(file_tmp,"%s\n",inci_file);
		fclose(file_tmp);
		free(temporal);
		return OK;
	}else{
		free(temporal);
		return ERROR_N_FOUND;
	}
}
	int valida(int accion,int pasos,char *argumento[], int argumentoc){
		int i;
		int contador = pasos;
		for(i=0;i<argumentoc;i++){
			if ((accion == 1)&&((!strcmp(argumento[i],"-f"))||(!strcmp(argumento[i],"-t"))||(!strcmp(argumento[i],"-u"))||
					(!strcmp(argumento[i],"-p"))||(!strcmp(argumento[i],"-a"))||(!strcmp(argumento[i],"-n"))||(!strcmp(argumento[i],"-s"))||
					(!strcmp(argumento[i],"-d")))){
				contador --;
				}
			if ((accion == 2)&&((!strcmp(argumento[i],"-f"))||(!strcmp(argumento[i],"-i"))||(!strcmp(argumento[i],"-u"))||
					(!strcmp(argumento[i],"-e")))){
				contador --;
				}
			if ((accion == 3)&&((!strcmp(argumento[i],"-f"))||(!strcmp(argumento[i],"-i"))||(!strcmp(argumento[i],"-r"))||
                                (!strcmp(argumento[i],"-u")))){
				contador --;
				}
			if ((accion == 4)&&(!strcmp(argumento[i],"-i"))){
				contador --;
				}
			if ((accion == 5)&&(!strcmp(argumento[i],"-i"))){
				contador --;
				}
			if ((accion == 6)&&(!strcmp(argumento[i],"-u"))){
				contador --;
				}
			if ((accion == 7)&&(!strcmp(argumento[i],"-n"))){
				contador --;
				}
			if ((accion == 8)&&(!strcmp(argumento[i],"-j"))){
				contador --;
				}
			if ((accion == 9)&&(!strcmp(argumento[i],"-k"))){
				contador --;
				}
			}
			return contador;
		}

int main(int argc, char *argv[]){
	int pasos,paso;


	/* Nobre de ejecucion para salidas de error e informacion */
	program_name = argv[0];
	while ((argc > 1) && (argv[1][0] == '-')) {
		paso = 0;
		 /* argv[1][1] es el caracter de la opcion actual.
		 */
		switch (argv[1][1]) {
			case 'I':
				accion = 0;
				if (argv[2]!=NULL){
				inci_file = strdup(argv[2]);
				if (file_exists(inci_file) == ERROR_N_FOUND){
					fprintf(stderr,"No se encontro %s para la opcion -I\n",inci_file);
				}else{sin_configuracion = 0;}}
			break;
			case 'P':
				accion = 0;
				if (argv[2]!=NULL){
				proyect_file = strdup(argv[2]);
				if (file_exists(proyect_file) == ERROR_N_FOUND){
					fprintf(stderr,"No se encontro %s para la opcion -P\n",proyect_file);
				}else{sin_configuracion = 0;}}
			break;
			case 'U':
				accion = 0;
				if (argv[2]!=NULL){
				user_file = strdup(argv[2]);
				if (file_exists(user_file) == ERROR_N_FOUND){
					fprintf(stderr,"No se encontro %s para la opcion -U\n",user_file);
				}else{sin_configuracion = 0;}}
			break;
			case 'A':
				paso=1;
				accion = 1;/*Agregar incidencia*/
				pasos = 8;
				if (valida(accion,pasos,argv,argc))
					uso();
			break;
			case 'E':
				paso=1;
				accion = 2;/*Cambiar estado*/
				pasos = 4;
				if (valida(accion,pasos,argv,argc))
					uso();
			break;
			case 'R':
				paso=1;
				accion = 3;/*Resolver incidencia*/
				pasos = 4;
				if (valida(accion,pasos,argv,argc))
					uso();
			break;
			case 'O':
				paso=1;
				accion = 4;/*Obtener datos incidencia*/
				pasos = 1;
				if (valida(accion,pasos,argv,argc))
					uso();
			break;
			case 'C':
				paso=1;
				accion = 5;/*Ontener comentarios incidencia*/
				pasos = 1;
				if (valida(accion,pasos,argv,argc))
					uso();
			break;
			case 'S':
				paso=1;
				accion = 6;/*Ontener incidencias usuario*/
				pasos = 1;
				if (valida(accion,pasos,argv,argc))
					uso();
			break;
			case 'Y':
				paso=1;
				accion = 7;/*Ontener incidencias proyecto*/
				pasos = 1;
				if (valida(accion,pasos,argv,argc))
					uso();
			break;
			case 'T':
				paso=1;
				accion = 8;/*Agregar un proyecto*/
				pasos = 1;
				if (valida(accion,pasos,argv,argc))
					uso();
			break;
			case 'G':
				paso=1;
				accion = 9;/*Agregar un usuario*/
				pasos = 1;
				if (valida(accion,pasos,argv,argc))
					uso();
			break;

			case 't':
				if (!(((argv[2][0]>='0')&&(argv[2][0]<'4'))&&(inci_tipo = atoi(argv[2])))){
				fprintf(stderr,"Parametro incorrecto %s para %s\n", argv[2],argv[1]);
				uso();
				}
			break;
			case 'p':
				if (!(((argv[2][0]>='0')&&(argv[2][0]<'5'))&&(inci_prior = atoi(argv[2])))){
				fprintf(stderr,"Parametro incorrecto %s para %s\n", argv[2],argv[1]);
				uso();
				}
			break;
			case 'u':
				if (!(id_u_create = atoi(argv[2]))){
				fprintf(stderr,"Parametro incorrecto %s para %s\n", argv[2],argv[1]);
				uso();
				}
			break;
			case 'e':
				if (!(((argv[2][0]>='0')&&(argv[2][0]<'5'))&&(inci_stat = atoi(argv[2])))){
                    fprintf(stderr,"Parametro incorrecto %s para %s\n", argv[2],argv[1]);
                    uso();
				}
			break;
			case 'a':
				if (!(id_u_asig = atoi(argv[2]))){
				fprintf(stderr,"Parametro incorrecto %s para %s\n", argv[2],argv[1]);
				uso();
				}
			break;
			case 'r':
				if (!(((argv[2][0]>='0')&&(argv[2][0]<'3'))&&(inci_resol = atoi(argv[2])))){
                    fprintf(stderr,"Parametro incorrecto %s para %s\n", argv[2],argv[1]);
                    uso();
				}
			break;
			case 'i':
				if (!(inci_ID = atoi(argv[2]))){
				fprintf(stderr,"Parametro incorrecto %s para %s\n", argv[2],argv[1]);
				uso();
				}
			break;
			case 'f':
				if (!(fecha=argv[2])){
				fprintf(stderr,"Parametro incorrecto %s para %s\n", argv[2],argv[1]);
				uso();
				}
			break;
			case 'n':
				if (!(inci_n_proy=atoi(argv[2]))){
				fprintf(stderr,"Parametro incorrecto %s para %s\n", argv[2],argv[1]);
				uso();
				}
			break;
			case 's':
				inci_summ = strdup(argv[2]);
			break;
			case 'j':
				proyname = strdup(argv[2]);
			break;
			case 'k':
				username = strdup(argv[2]);
			break;
			case 'd':
				inci_desc = strdup(argv[2]);
			break;
			default:
					fprintf(stderr,"Parametro incorrecto %s\n", argv[1]);
					uso();
		}
		/*
		 * aumento la lista de argumentos
		 * bajo la cantidad de argumentos
		 */
		argv = argv + (2 - paso);
		argc = argc - (2 -paso);
	}
	if (inci_stat = TIN_OPEN)
        estado="TIN_OPEN";
	else if (inci_stat = TIN_PROGRESS)
        estado="TIN_PROGRESS";
	else if (inci_stat = TIN_RESOLVED)
        estado="TIN_RESOLVED";
	else if (inci_stat = TIN_REOPEN)
        estado="TIN_REOPEN";
    else if (inci_stat = TIN_CLOSED)
        estado="TIN_CLOSED";


	if (accion != 0){
		FILE *file_tmp;
		int error;
		char *temporal;
		char *nombre=(char*)malloc(sizeof(char*)*50);
	//	char *temporal=(char*)malloc(sizeof(char*)*(strlen(program_name)));
		temporal = strdup(program_name);
		temporal=realloc(temporal, sizeof(char*)*(strlen(program_name)+5));
		strcat(temporal,".ini");
		if (file_exists(temporal) == OK){
			file_tmp = fopen(temporal, "r");

			error = fscanf(file_tmp,"%s",nombre);
			proyect_file = (strdup(nombre));

			error = fscanf(file_tmp,"%s",nombre);
			user_file = strdup(nombre);

			error = fscanf(file_tmp,"%s",nombre);
			inci_file = strdup(nombre);
			fclose(file_tmp);
			free(temporal);
			free(nombre);
		}else{
			fprintf(stderr,"Error de configuracion en el archivo %s.ini\n",program_name);
			free(temporal);
			free(nombre);
			uso();

			}
	}
	int i;
	switch (accion){
			case 0:
				if (proyect_file==NULL||user_file==NULL||inci_file==NULL){
					fprintf(stderr,"Debe ingresar todos los nombres de archivo\n");
					uso();
					}
				configuracion(program_name,proyect_file,user_file,inci_file);
				return OK;
			break;

			case 1:
				TGI_Crear (&tgi,proyect_file,user_file,inci_file);

				printf("Salio de TGI_Crear\n");
				printf("En el MAIN - Usuarios Corriente: %p\n",tgi.proyectos.Cte);
				for (i=0;i<strlen(inci_summ);i++){
					if (inci_summ[i]== ' ') inci_summ[i]='·';
					}
				for (i=0;i<strlen(inci_desc);i++){
					if (inci_desc[i]== ' ') inci_desc[i]='·';
					}
				fprintf(stderr,"Error: %d\n",TGI_AgregarIncidencia (&tgi,inci_tipo,inci_prior,id_u_create,id_u_asig,fecha,inci_n_proy,inci_summ,inci_desc));
			break;
			case 2:/*Cambiar estado*/
				TGI_Crear (&tgi,proyect_file,user_file,inci_file);
				TGI_GetIncidencia(&tgi, inci_ID, &tin);
				TIN_CambiarEstado(&tin,fecha,id_u_create,estado);
				TGI_Modificar_Incidencia(&tgi,&tin);

			break;
			case 3:/*Resolver incidencia*/
				TGI_Crear (&tgi,proyect_file,user_file,inci_file);
				TGI_GetIncidencia(&tgi, inci_ID, &tin);
				TIN_Resolver(&tin,fecha,id_u_create,inci_resol);
				TGI_Modificar_Incidencia(&tgi,&tin);

			break;
			case 4:/*Obtener datos incidencia*/
				TGI_Crear (&tgi,proyect_file,user_file,inci_file);
				TGI_GetIncidencia(&tgi, inci_ID, &tin);
				inci_summ = strdup(tin.inci_description);
				inci_desc = strdup(tin.inci_description);
				for (i=0;i<strlen(inci_summ);i++){
					if (inci_summ[i]== '·') inci_summ[i]=' ';
					}
				for (i=0;i<strlen(inci_desc);i++){
					if (inci_desc[i]== '·') inci_desc[i]=' ';
					}
				printf("\n\n");

				printf("id incidencia %d\n",tin.inci_id);
				printf("tipo de incidencia %d\n",tin.inci_type);
				printf("prioridad de la incidencia %d\n",tin.inci_priority);
				printf("usuario de incidencia %d\n",tin.inci_user);
				printf("usuario asignado %d\n",tin.inci_assigned_user);
				printf("dia de creacion de la incidencia %s\n",tin.inci_date_created);
				printf("id de proyecto %d\n", tin.inci_project_id);
				printf("resumen %s\n",inci_summ);
				printf("descripcion %s\n",inci_desc);

			break;
			case 5:/*Ontener comentarios incidencia*/
				TGI_Crear (&tgi,proyect_file,user_file,inci_file);
				TGI_GetIncidencia(&tgi, inci_ID, &tin);
				LS_Crear(&incidencias3,sizeof(inci_comment_t));
				TIN_GetListaComentarios(&tin, &incidencias3);
				LS_MoverCte(&incidencias3,LS_PRIMERO);
				while(!(LS_Vacia(incidencias3))){
				    LS_ObtenerCte(incidencias3,&comentarios);
				    printf("Comentario de %i, %s - %s\n",comentarios.comm_user_id,comentarios.comm_date,comentarios.comm_desc);
				    LS_BorrarCte(&incidencias3);
				    }
			break;
			case 6:/*Ontener incidencias usuario*/
				TGI_Crear (&tgi,proyect_file,user_file,inci_file);
				if(TGI_GetIncidenciasUsuario(&tgi,id_u_asig, &incidencias2)==0){
				while (!C_Vacia(incidencias2)){
					C_Sacar(&incidencias2, &tin);
					printf("Incidencia ID: %d  del Usuario: %d\n",tin.inci_id,id_u_asig);
					}
				}
			break;
			case 7:/*Ontener incidencias proyecto*/
				TGI_Crear (&tgi,proyect_file,user_file,inci_file);
				if(!TGI_GetIncidenciasProyecto(&tgi,inci_n_proy, &incidencias3)){
				LS_MoverCte (&incidencias3, LS_PRIMERO);
				while (incidencias3.Cte->Sig!=NULL){
					LS_ObtenerCte (incidencias3, &tin);
					printf("Incidencia ID: %d\n",tin.inci_id);
					LS_MoverCte (&incidencias3, LS_SIGUIENTE);
				}
				if (incidencias3.Prim!=NULL){   //Ultimo dato que se pierde por el corte del while
					LS_ObtenerCte (incidencias3, &tin);
					printf("Incidencia ID: %d\n",tin.inci_id);
					}
				}
			break;
			case 8:/*Agregar un proyecto*/
				TGI_Crear (&tgi,proyect_file,user_file,inci_file);
				Agregar_Proyecto (&tgi,proyect_file,proyname);
			break;
			case 9:/*Agregar un usuario*/
				TGI_Crear (&tgi,proyect_file,user_file,inci_file);
				Agregar_Usuario (&tgi,user_file,username);
			break;
			default:
				return 0;
		}

  TGI_Cerrar( &tgi);
	free(inci_file);
	free(proyect_file);
	free(user_file);
  return exeStatus;
}
